package main

import (
	"errors"
	"flag"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"regexp"
	"strings"
)

var (
	protoPath string
	outputPath string

	packageRegex *regexp.Regexp
	messageRegex *regexp.Regexp
)

func init() {
	flag.StringVar(&protoPath, "proto_path", "", "proto message directory path")
	flag.StringVar(&outputPath, "output_path", "", "output directory path")

	packageRegex = regexp.MustCompile(`package[[:space:]]+[[:word:]\.]+;`)
	messageRegex = regexp.MustCompile(`message[[:space:]]*[[:word:]]+[[:space:]]*\{[^\}]*\}`)
}

func main() {
	flag.Parse()

	var err error
	defer func() {
		if err != nil {
			log.Printf("generate code failed, reason: %s", err)
		}
	}()


	if err = loadProtoFiles(); err != nil {
		return
	}
}

func loadProtoFiles() (err error) {
	var files []string
	if files, err = getFiles(protoPath); err != nil {
		return
	}

	//fmt.Print(strings.Join(files, "\n"))
	for _, item := range files {
		handleFile(item)
	}

	return
}

func getFiles(dirPath string) (results []string, err error) {
	var fileInfos []os.FileInfo
	if fileInfos, err = ioutil.ReadDir(dirPath); err != nil {
		return
	}

    for _, item := range fileInfos {
        if item.IsDir() {
        	var files []string
        	if files, err = getFiles(filepath.Join(dirPath, item.Name())); err != nil {
        		return
			}
            results = append(results, files...)
        } else {
        	const suffix = ".proto"
            if strings.HasSuffix(item.Name(), suffix) {
                results = append(results, filepath.Join(dirPath, item.Name()))
            }
        }
    }

	return
}

func handleFile(name string) (err error) {
	var data []byte
	if data, err = ioutil.ReadFile(name); err != nil {
		return
	}

	var packageName string
	text := string(data)
	if packageName = packageRegex.FindString(text); len(packageName) < 1 {
		err = errors.New("not package name")
		return
	} else {
		packageName = filterPackageName(packageName)
		_ = packageName
	}

	if messages := messageRegex.FindAllStringSubmatch(text, -1); len(messages) < 1 {
		return
	} else {
		_ = messages
	}


	return
}

func filterPackageName(name string) string {
	const begin = len("package")
	name = name[begin:len(name)-1]
	name = strings.TrimSpace(name)
	name = strings.ReplaceAll(name, ".", "_")

	return name
}
